<?php

namespace Applications\XChat;

class Events {

	/**
	 * IP 黑名单列表
	 */
	public static $ipBlackList = [];

	/**
	 * 用户连接
	 * 索引为用户 UID
	 */
	public static $connections = [];

	public static function onWorkerStart($worker) {
		Data::init();
		Data::clearConnections();

		//初始化IP黑名单
		self::$ipBlackList = Data::getIpBlackList();

		if (self::$ipBlackList === false) {
			echo '读取黑名单失败: '.Data::getError();
			self::$ipBlackList = [];
		}
	}

	public static function onConnect($connection) {
		//IP 黑名单限制
		if (in_array($connection->getRemoteIp(), self::$ipBlackList)) {
			$connection->destroy();
			return;
		}

		$now = time();

		$connection->onWebSocketConnect = function($connection) use ($now) {
			if (!isset($_GET['hash'])) {
				$connection->close();
				return;
			}

			if (!preg_match('/^\w{32}$/', $_GET['hash'])) {
				$connection->close();
				return;
			}

			//获取用户
			$user = Data::getUserByHash($_GET['hash']);

			if (!$user) {
				$uid = md5(rand(10000, 99999).'-'.$connection->id.'-'.uniqid('', true));
				Data::addUser($uid, $_GET['hash']);
			} else {
				$uid = $user['uid'];
				Data::updateUser($uid, ['last_login'=>$now]);
			}

			//注册连接
			$connection->uid = $uid;
			$connection->nickname = $user ? $user['nickname'] : '';
			$connection->lastActive = time(); //最后活跃时间
			$connection->lastSend = microtime(true); //最后发送消息时间

			//替换已有的登录
			$myConnections = Data::getConnectionsByUid($uid);
			$isReplaced = false;

			foreach ($myConnections as $conn) {
				if ($conn['id'] != $connection->id && isset($connection->worker->connections[$conn['id']])) {
					$otherConn = $connection->worker->connections[$conn['id']];
					$otherConn->replaced = true;
					Helper::send($otherConn, ['type' => 'out', 'status' => 'replaced']);
					$otherConn->close();
					$isReplaced = true;
				}
			}

			Data::addConnection($connection);
			self::$connections[$uid] = $connection;

			//返回信息
			Helper::send($connection, ['type'=>'baseinfo', 'uid'=>$connection->uid, 'nickname'=>$connection->nickname]);
			$isReplaced || Helper::userStateChange($connection, true);
			Helper::sendOnlineList($connection);
		};
	}

	public static function onClose($connection) {
		if (!isset($connection->uid)) {
			return;
		}

		Data::removeConnection($connection->id);

		if (!isset($connection->replaced)) {
			Helper::userStateChange($connection, false);
			unset(self::$connections[$connection->uid]);
		}
	}

	/**
	 * @param \Workerman\Connection\TcpConnection $connection
	 * @param mixed $data
	 */
	public static function onMessage($connection, $data) {
		if (!isset($connection->uid)) {
			Helper::error($connection, '您尚未注册');
			return;
		}

		$data = @json_decode($data, true);

		if (!is_array($data) || !isset($data['type'])) {
			Helper::error($connection, '数据格式错误');
			return;
		}

		//调用消息
		$call = '\Applications\XChat\Message::'.$data['type'];

		if (is_callable($call)) {
			$res = call_user_func($call, $connection, $data);
			is_array($res) && Helper::send($connection, $res);
		} else {
			Helper::error($connection, '数据格式错误');
		}

		$connection->lastActive = time();
	}

}
